/*
	This file is part of Qonverter.
	
	Qonverter is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.
	
	Qonverter is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.
	
	You should have received a copy of the GNU General Public License
	along with Qonverter.  If not, see <http://www.gnu.org/licenses/>.
	
	Copyright 2012 - 2013 Martin Rotter
*/

#ifndef CALCULATORHIGHLIGHTER_H
#define CALCULATORHIGHLIGHTER_H

#include <QSyntaxHighlighter>
#include <QHash>
#include <QTextCharFormat>


// Inspiration:
// http://qt-project.org/doc/qt-5.0/qtwidgets/richtext-syntaxhighlighter.html
struct ParenthesisInfo {
    char m_character;
    int m_position;
};

class TextBlockData : public QTextBlockUserData {
  public:
    // Constructors and destructors.
    explicit TextBlockData();
    ~TextBlockData();

    // Returns collection of stored parenthesises.
    QVector<ParenthesisInfo*> getParenthesises();

    // Inserts info about new parenthesis into collection.
    void insert(ParenthesisInfo *info);

  private:
    QVector<ParenthesisInfo*> m_parentheses;
};

// Stores information about highlighteable element.
struct HighlightingRule {
    // Pattern to highlight.
    QRegExp m_pattern;

    // Format of highlighted piece of text, ie. the color.
    QTextCharFormat m_format;
};

class CalculatorInput;

class CalculatorHighlighter : public QSyntaxHighlighter {
    Q_OBJECT

  public:
    enum HighlighterRole {
      NUMBERS,
      FUNCTIONS,
      OPERATORS,
      BRACES_B,
      BRACES_F,
      STRINGS
    };

    // Constructor.
    explicit CalculatorHighlighter(CalculatorInput *parent);

    // Initializes colors for all elements from application-wide settings.
    void initializeColors(const QList<QColor> &colors = QList<QColor>());

    // Returns rule (with formatting) for given element type.
    HighlightingRule getRule(const HighlighterRole &type);

    // Sets or gets color (to/from application-wide settings)
    // for certain element, if no setting is found, then
    // color from adaptive coloring is used.
    QColor getColorForToken(const HighlighterRole &type);
    void setColorForToken(const HighlighterRole &type, const QColor &color);

    // Returns default colors generated by adaptive coloring
    // algorithm.
    QList<QColor> getDefaultColors();

  protected:
    void highlightBlock(const QString &text);

    // Adaptive coloring algorithm.
    // http://doc.qt.digia.com/qq/qq26-adaptivecoloring.html
    QList<QColor> generateAdaptiveColors(const QColor &bg, const QColor &fg, int no_colors);

  private:
    CalculatorInput *m_input;
    QList<HighlightingRule> m_highlightingRules;
    QList<QColor> m_correctColors;
    QList<QString> m_ruleKeys;
};

#endif // CALCULATORHIGHLIGHTER_H
